﻿using UnityEngine;
using UnityEngine.UI;
using System.Collections.Generic;
//该脚本只在编辑器模式下使用，用于创建不可达点
public class GetUnMovableCells : MonoBehaviour
{
    public HashSet<Vector2Int> UnreachableHexCells; //用Vector2Int是因为x+y+z=0，所以不用保存z
    public int MaxCoor { get; private set; }
    [SerializeField]
    public HexagnoalMapData m_MapData;
    float innerRadius, outerRadius;
    GameObject hexCell;
    GameObject unmoveableCell;
    public Text ShowResText;

    public GameObject AIObject;

    public GameObject Tip3;

    int maxUnReachCount;
    public GameObject Tip4;
    protected void Start()
    {
        UnreachableHexCells = new HashSet<Vector2Int>(Vector2IntComparer.GetComperer());
        gameObject.AddComponent<MeshFilter>().mesh = m_MapData.MapMesh;
        gameObject.AddComponent<MeshRenderer>().sharedMaterial = m_MapData.MapMaterial;
        gameObject.AddComponent<MeshCollider>().sharedMesh = m_MapData.MapMesh;
        Initialize(m_MapData.EdgeCount, m_MapData.OuterRadius);
        hexCell = new GameObject("Mouse");
        hexCell.AddComponent<MeshFilter>().mesh = m_MapData.CellMesh;
        hexCell.AddComponent<MeshRenderer>().sharedMaterial = m_MapData.CellMaterial;
        unmoveableCell = new GameObject("Unmovable");
        unmoveableCell.AddComponent<MeshFilter>().mesh = m_MapData.CellMesh;
        unmoveableCell.AddComponent<MeshRenderer>().sharedMaterial = m_MapData.UnmovableMaterial;
        unmoveableCell.SetActive(false);
        maxUnReachCount = MaxCoor * 4;
        ShowResText.text = maxUnReachCount.ToString();
    }
    public void Initialize(int edgeCount, float outerRadius)
    {
        MaxCoor = edgeCount - 1;
        innerRadius = outerRadius * 0.866025404f;
        this.outerRadius = outerRadius;
    }

    public Vector2Int GetCoor(Vector3 position)
    {
        //红为X，绿为Y，蓝为Z，由于该坐标系的特殊性，距离某一轴多少单位就是该轴分量的值
        //如距离X轴2单位，则X轴分量为2
        position = transform.InverseTransformPoint(position);
        float x = position.x / (innerRadius * 2f);
        float y = -x;
        float offset = position.z / (outerRadius * 3f);
        x -= offset;
        y -= offset;
        int ix = Mathf.RoundToInt(x);
        int iy = Mathf.RoundToInt(y);
        int iz = Mathf.RoundToInt(-x - y);
        if (ix + iy + iz != 0) //消除舍入误差
        {
            float dX = Mathf.Abs(x - ix);
            float dY = Mathf.Abs(y - iy);
            float dZ = Mathf.Abs(-x - y - iz);
            if (dX > dY && dX > dZ)
            {
                ix = -iy - iz;
            }
            else if (dY > dZ)
            {
                iy = -iz - ix;
            }
        }
        return new Vector2Int(ix, iy);
    }
    public Vector3 GetPosition(Vector2Int coor)
    {
        //在一个六边形单元格子中并不是所有点都可以用它的逆变换来求出在六边形坐标系上的坐标，因为在这种六边形坐标中班只有整点才满足x+y+z=0
        int z = -coor.x - coor.y;
        return transform.TransformPoint(new Vector3((coor.x - coor.y) * innerRadius, 0f, z * outerRadius * 1.5f));
    }
    /// <summary>
    /// 返回true，可到达点
    /// </summary>
    /// <param name="point"></param>
    /// <returns></returns>
    public bool IsReachablePoint(Vector2Int point)
    {
        return !UnreachableHexCells.Contains(point);
    }
    bool keydownFlag;
    private void Update()
    {
        RaycastHit hitInfo;
        if (Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out hitInfo))
        {
            hexCell.SetActive(true);
            Vector2Int coor = GetCoor(hitInfo.point);
            Vector3 pos = GetPosition(coor) + Vector3.up * 0.05f;
            hexCell.transform.position = pos;
            if (maxUnReachCount > 0 && Input.GetMouseButtonDown(1))
            {
                if (UnreachableHexCells.Add(coor))
                {
                    GameObject go = Instantiate(unmoveableCell);
                    go.transform.parent = transform;
                    go.SetActive(true);
                    go.transform.position = pos;
                    maxUnReachCount--;
                    ShowResText.text = maxUnReachCount.ToString();
                }
            }
        }
        else
            hexCell.SetActive(false);

        if (Input.GetKeyUp(KeyCode.J) || maxUnReachCount == 0)
        {
            //BinaryWriter bw = new BinaryWriter(new FileStream(Application.dataPath + "//unReachPoint.txt", FileMode.OpenOrCreate));
            //bw.Write(UnreachableHexCells.Count);
            //foreach (var item in UnreachableHexCells)
            //{
            //    bw.Write(item.x);
            //    bw.Write(item.y);
            //}
            //bw.Close();
            ShowResText.transform.parent.gameObject.SetActive(false);
            HexagnoalMap map = gameObject.AddComponent<HexagnoalMap>();
            map.hexCell = hexCell;
            map.Initialize(MaxCoor + 1, outerRadius);
            map.UnReachableHexCells = UnreachableHexCells;
            Transform ai = Instantiate(AIObject).transform;
            float val = outerRadius * MaxCoor;
            Vector3 pos = new Vector3(Random.Range(-val, val), 0, Random.Range(-val, val));
            while (UnreachableHexCells.Contains(GetCoor(pos)))
            {
                pos = new Vector3(Random.Range(-val, val), 0, Random.Range(-val, val));
            }
            ai.position = pos;
            enabled = false;
            Tip4.SetActive(true);
        }
    }
}
